package com.linc.base64;

import android.content.CursorLoader;
import android.content.Intent;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Environment;
import android.provider.MediaStore;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Base64;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.TextView;

import com.android.widget.demo.R;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;

public class Base64Activity extends AppCompatActivity {
    private static final String TAG = "Base64Activity";
    private static final int OPEN_PHOTO_FOLDER_REQUEST_CODE = 1001;
    private TextView mTvShow;
    private static final String PATH_DECODE = Environment.getExternalStorageDirectory().getPath()
            +"/decodeText.txt";
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_base64);
        mTvShow = (TextView)findViewById(R.id.tv_show_base64_string);
    }

    public void onEncodeClicked(View view) {

        //select picture
        Intent intent = new Intent();
        intent.setType("image/*");
        intent.setAction(Intent.ACTION_GET_CONTENT);
        startActivityForResult(intent, OPEN_PHOTO_FOLDER_REQUEST_CODE);

        //test charactor
//        String test = "hello linc!!!I will be back this week.";
//        String testBase64 = Base64.encodeToString(test.getBytes(),Base64.DEFAULT);
//        mTvShow.setText(testBase64);
//        Log.d(TAG,"base64: "+testBase64);
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if(OPEN_PHOTO_FOLDER_REQUEST_CODE == requestCode && RESULT_OK == resultCode) {

            //encode the image
            Uri uri = data.getData();
            try {
                //get the image path
                String[] projection = {MediaStore.Images.Media.DATA};
                CursorLoader cursorLoader = new CursorLoader(this,uri,projection,null,null,null);
                Cursor cursor = cursorLoader.loadInBackground();
                int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
                cursor.moveToFirst();

                String path = cursor.getString(column_index);
                Log.d(TAG,"real path: "+path);
                //decode to bitmap
                Bitmap bitmap = BitmapFactory.decodeFile(path);
                Log.d(TAG, "bitmap width: " + bitmap.getWidth() + " height: " + bitmap.getHeight());
                //convert to byte array
//                ByteArrayOutputStream baos = new ByteArrayOutputStream();
//                bitmap.compress(Bitmap.CompressFormat.PNG, 100, baos);
//                byte[] bytes = baos.toByteArray();
//                Log.d(TAG,"bitmap convert bytes success.");
                //gray it and convert byte array
                byte[] bytes = convertGreyImg(bitmap);

                //base64 encode
//                byte[] encode = Base64.encode(bytes,Base64.DEFAULT);
//                String encodeString = new String(encode);
                String encodeString = Base64.encodeToString(bytes,Base64.DEFAULT);
                mTvShow.setText("encode ok.");
                //write to file
                FileWriter writer = new FileWriter(PATH_DECODE);
                writer.write(encodeString);
                Log.d(TAG, "write ok.");
                writer.close();
            } catch (Exception ex) {
                Log.e(TAG, "failed." + ex.getMessage());
            }
        }
    }

    public void onDecodeClicked(View view) {
        try {
            //read base64 string from file
            BufferedReader reader = new BufferedReader(new InputStreamReader(
                    new FileInputStream(new File(PATH_DECODE))));
            StringBuffer base64String = new StringBuffer("");
            String tmp;
            while ((tmp = reader.readLine()) != null) {
                base64String.append(tmp);
            }
            reader.close();
            Log.d(TAG, "read decode file ok.");
            byte[] decode = Base64.decode(base64String.toString(),Base64.DEFAULT);
            Log.d(TAG,"decode length: "+decode.length);
//            Bitmap bitmap = BitmapFactory.decodeByteArray(decode, 0, decode.length);
//            Log.d(TAG,"bitmap height: "+bitmap.getHeight());
            //save to image on sdcard
//            saveBitmap(bitmap);

            //save gray image
            int[] data2 = byteArray2intArray(decode);
            saveBitmap(data2, 600, 600);

            //decode string
//        byte[] decode = Base64.decode(mTvShow.getText().toString(),Base64.DEFAULT);
//        mTvShow.setText(new String(decode));
        }catch (Exception ex) {
            Log.e(TAG,"decode failed. "+ex.getMessage());
        }
    }

    private void saveBitmap(Bitmap bitmap) {
        try {
            String path = Environment.getExternalStorageDirectory().getPath()
                    +"/decodeImage2.jpg";
            Log.d("linc", "path is " + path);
            OutputStream stream = new FileOutputStream(path);
            bitmap.compress(Bitmap.CompressFormat.JPEG, 90, stream);
            stream.close();
            Log.e("linc","jpg okay!");
        } catch (IOException e) {
            e.printStackTrace();
            Log.e("linc","failed: "+e.getMessage());
        }
    }

    private void saveBitmap(int[] data,int width,int height) {
        Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565);
        bitmap.setPixels(data, 0, width, 0, 0, width, height);
        saveBitmap(bitmap);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_base64, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) {
            return true;
        }

        return super.onOptionsItemSelected(item);
    }

    public byte[] convertGreyImg(Bitmap img) {
        int width = img.getWidth();
        int height = img.getHeight();

        int len=width*height;
        int[] pixels = new int[len];
        byte[] buffer = new byte[len];
        img.getPixels(pixels, 0, width, 0, 0, width, height);
        int alpha = 0xFF << 24;
        int color,red,green,blue;
        for (int i = 0; i < len; i++) {
            color = pixels[i];
            red = ((color & 0x00FF0000) >> 16);
            green = ((color & 0x0000FF00) >> 8);
            blue = color & 0x000000FF;
            color = (red*299+green*587+blue*114+500) / 1000;
            color = alpha | (color << 16) | (color << 8) | color;
            pixels[i] = color;
            buffer[i] = (byte)color;
        }
        return buffer;
    }

    public int[] byteArray2intArray(byte[] data) {
        int[] buffer = new int[data.length];
        for (int i = 0;i<data.length;i++) {
            buffer[i] = (int)data[i];
        }
        return buffer;
    }

    /**
     * decode J2SE
     *
     */
    /*
    public class TestBase64 {
        public static void main(String[] args) {
            sun.misc.BASE64Decoder decoder = new sun.misc.BASE64Decoder();
            sun.misc.BASE64Encoder encoder = new sun.misc.BASE64Encoder();
            try {
                String test = "aGVsbG8gbGluYyEhIUkgd2lsbCBiZSBiYWNrIHRoaXMgd2Vlay4=";
                System.out.println("test is : " + test);
                byte[] f3 = decoder.decodeBuffer(test);
                String decodeTest = new String(f3);
                System.out.println("decodeTest is : " + decodeTest);
            } catch (Exception ex) {
                System.err.println("error: " + ex.getMessage());
            }
        }
    }
    */
}
